package com.linkstec.mongo;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.bson.Document;
import org.bson.conversions.Bson;

import com.linkstec.mongo.SubscriberHelpers.ObservableSubscriber;
import com.linkstec.mongo.SubscriberHelpers.OperationSubscriber;
import com.linkstec.util.ConfigUtil;
import com.mongodb.ConnectionString;
import com.mongodb.MongoClientSettings;
import com.mongodb.client.model.Filters;
import com.mongodb.client.model.UpdateOptions;
import com.mongodb.client.model.Updates;
import com.mongodb.client.result.UpdateResult;
import com.mongodb.reactivestreams.client.MongoClient;
import com.mongodb.reactivestreams.client.MongoClients;
import com.mongodb.reactivestreams.client.MongoCollection;
import com.mongodb.reactivestreams.client.MongoDatabase;

/**
 * 不能和同步驱动共存 cpu100%
 * 
 * @author liulu
 *
 */
public class MongoDbReactiveUtil {

	private static final Logger logger = LogManager.getLogger();
	private static String hostsAndPorts;
	private static String userNameDatabasePassword;
	private static MongoClient mongoClient = null;
	private static MongoDatabase testDatabase;
	private static MongoCollection<Document> collection;

	static {
		hostsAndPorts = "192.168.2.232:30000,192.168.2.233:30000,192.168.2.234:30000";
		userNameDatabasePassword = ConfigUtil.getProperty("userNameDatabasePassword", "mot,MOT,Gtjamot@123");
	}

	// connect to mongodb
	public static MongoClient getMongoClient() {
		if (null == mongoClient) {

			String[] credential = userNameDatabasePassword.split(",");
			String connectionStr = null;
			try {
				connectionStr = "mongodb://" + credential[0] + ":" + URLEncoder.encode(credential[2], "UTF-8") + "@"
						+ hostsAndPorts + "/" + credential[1];
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}
			logger.info(connectionStr);
			ConnectionString connectionString = new ConnectionString(connectionStr);
			MongoClientSettings mongoClientSettings = MongoClientSettings.builder()
					.applyConnectionString(connectionString).build();

			mongoClient = MongoClients.create(mongoClientSettings);

			return mongoClient;
		} else {
			return mongoClient;
		}
	}

	public static MongoDatabase getMongoDatabase(String mongoDatabase) {
		mongoClient = getMongoClient();
		testDatabase = mongoClient.getDatabase(mongoDatabase);
		logger.info("获得testDatabase");
		return testDatabase;
	}

	public static MongoCollection<Document> getMongoCollection(MongoDatabase mongoDatabase, String collectionName) {
		collection = mongoDatabase.getCollection(collectionName);
		return collection;
	}

	public static MongoCollection<Document> getMongoCollection(String mongoDatabase, String collectionName) {
		mongoClient = getMongoClient();
		testDatabase = mongoClient.getDatabase(mongoDatabase);
		collection = testDatabase.getCollection(collectionName);
		return collection;
	}

	public static void main(String[] args) {
		MongoCollection<Document> users = getMongoCollection("MOT", "users");

		Document user = new Document();
		user.put("name", "jimmy");
		user.put("age", "34");
		user.put("工作", "程序员");
		Document address = new Document();
		address.put("city", "bj");
		address.put("street", "bq road");
		address.put("mail", "ufpark 68#");
		/**
		 * 对于内嵌文档，我们需要先将内嵌文档填充后，再填充到外层文档中
		 */
		user.put("address", address);

		logger.info("" + users.countDocuments());
		logger.info("" + users.countDocuments());
		logger.info("----------------------------------华丽的分割线-------------------------------------------------");

		UpdateOptions updateOptions = new UpdateOptions();
		updateOptions.upsert(true);
		logger.info("----------------------------------华丽的分割线-------------------------------------------------");
		MongoCollection<Document> smotUserMessageConfig = getMongoCollection("MOT", "SMOT_USER_MESSAGE_CONFIG");
		logger.info(smotUserMessageConfig.countDocuments() + "");
		List<Bson> bsonList = new ArrayList<Bson>();
		Bson filters = null;
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
		bsonList.add(Filters.eq("userId", "018637"));
		bsonList.add(Filters.eq("eventId", "455"));
		bsonList.add(Filters.eq("toDay", sdf.format(new Date())));
		filters = Filters.and(bsonList);
		List<Bson> updateBsonList = new ArrayList<Bson>();
		updateBsonList.add(Updates.setOnInsert("userId", "018637"));
		updateBsonList.add(Updates.setOnInsert("eventId", "455"));
		updateBsonList.add(Updates.set("isApp", "1"));
		updateBsonList.add(Updates.setOnInsert("toDay", sdf.format(new Date())));
		updateBsonList.add(Updates.set("updateTime", new Date()));
		Bson document = Updates.combine(updateBsonList);

		long start = System.currentTimeMillis();
		for (int i = 0; i <= 100000; i++) {

			ObservableSubscriber<UpdateResult> updateSubscriber = new OperationSubscriber<>();
			smotUserMessageConfig.updateOne(filters, document, updateOptions).subscribe(updateSubscriber);
			updateSubscriber.onComplete();
			
			/*smotUserMessageConfig.updateOne(
					Filters.and(Filters.eq("userId", "018637"), Filters.eq("eventId", "455"),
							Filters.eq("toDay", sdf.format(new Date()))),
					Updates.combine(Updates.setOnInsert("userId", "018637"), Updates.setOnInsert("eventId", "455"),
							Updates.set("isNotice", "1"), Updates.set("isSms", "1"), Updates.set("isEmail", "1"),
							Updates.set("isApp", "1"), Updates.set("isWebmessage", "1"), Updates.set("isWechat", "1"),
							Updates.setOnInsert("toDay", sdf.format(new Date())),
							Updates.setOnInsert("createTime", new Date())),
					updateOptions).subscribe(updateSubscriber);
			updateSubscriber.onComplete();*/

		}
		long end = System.currentTimeMillis();
		logger.info((end - start) + "");
	}
}